package cn.tedu.luban.order.main.controller;

import cn.tedu.luban.order.common.enums.OrderResultEnum;
import cn.tedu.luban.order.main.converter.OrderConverter;
import cn.tedu.luban.order.main.service.OrderService;
import cn.tedu.luban.order.protocol.VO.FrontOrderDetailVO;
import cn.tedu.luban.order.protocol.VO.FrontOrderItemVO;
import cn.tedu.luban.order.protocol.bo.OrderBO;
import cn.tedu.luban.order.protocol.param.OrderConfirmParam;
import cn.tedu.luban.order.protocol.param.OrderCreateParam;
import cn.tedu.luban.order.protocol.param.OrderFinishParam;
import cn.tedu.luban.order.protocol.param.OrderSignParam;
import cn.tedu.luban.order.protocol.query.FrontOrderListQuery;
import cn.tedu.luban.passport.protocol.jwt.UserPrinciple;
import cn.tedu.luban.passport.sdk.security.LubanSecurityContext;
import com.tedu.inn.protocol.ListRecordTotalBO;
import com.tedu.inn.protocol.exception.BusinessException;
import com.tedu.inn.protocol.model.Result;
import com.tedu.inn.protocol.pager.PagerResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private OrderService orderService;


    @Autowired
    private OrderConverter orderConverter;

    @PostMapping("/order/create")
    public Result<String> orderCreate(@RequestBody OrderCreateParam orderCreateParam) throws BusinessException {
        //获取登陆的userId
        Long userId=getUserId();
        //组织key
        String reGrabKey="luban:request:grab:"+userId+":"+orderCreateParam.getRequestOrderNo();
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        //自增锁，设置超时
        Long increment = opsForValue.increment(reGrabKey);
        redisTemplate.expire(reGrabKey,3, TimeUnit.SECONDS);
        if (increment>1) {
            log.info("重复抢单");
            throw new BusinessException(OrderResultEnum.ORDER_RE_GRAB);
        }
        //调用业务层 进行抢单，生成订单，记录订单日志
        String orderNo=orderService.orderCreate(orderCreateParam);
        return new Result<>(orderNo);

    }

    private Long getUserId() throws BusinessException {
        UserPrinciple loginToken = LubanSecurityContext.getLoginToken();
        if (loginToken==null){
            throw new BusinessException(OrderResultEnum.USER_TOKEN_VERIFY_FAILED);
        }
        return loginToken.getId();
    }

    @PostMapping("/order/list")
    public Result<PagerResult<FrontOrderItemVO>> orderList(@RequestBody FrontOrderListQuery frontOrderListQuery) throws BusinessException {
        //1.调用业务层 返回 total list 封装返回对象
        ListRecordTotalBO<OrderBO> bos=orderService.orderList(frontOrderListQuery);

        //2.装配到PagerResult对象中
        PagerResult<FrontOrderItemVO> frontOrderItemVOPagerResult = orderConverter.assemblePagerResult(bos, frontOrderListQuery);

        return new Result<>(frontOrderItemVOPagerResult);
    }

    @GetMapping("/order/info")
    public Result<FrontOrderDetailVO> orderInfo(String orderNo) throws BusinessException{
        //1.调用业务层，返回出参是orderBO
        OrderBO orderBO=orderService.orderInfo(orderNo);
        //2.转换成detailVO返回
        FrontOrderDetailVO vo = orderConverter.bo2frontDetailVO(orderBO);
        return new Result<>(vo);
    }

    /**
     * 师傅签到
     */

    @PostMapping("/order/sign")
    public Result<String> orderSign(@RequestBody OrderSignParam orderSignParam) throws BusinessException{
        orderService.orderSign(orderSignParam);
        return new Result<>(orderSignParam.getOrderNo());
    }

    @PostMapping("/order/confirm")
    public Result<String> orderConfirm(@RequestBody OrderConfirmParam orderConfirmParam) throws BusinessException {
        //1.调用业务层
        orderService.orderConfirm(orderConfirmParam);
        //2.返回结果
        return new Result<>(orderConfirmParam.getOrderNo());
    }

    @PostMapping("/order/finish")
    public Result<String> orderFinish(@RequestBody OrderFinishParam orderFinishParam) throws BusinessException {
        //1.调用业务层
        orderService.orderFinish(orderFinishParam);
        //2.返回结果，表示请求成功
        return new Result<>(orderFinishParam.getOrderNo());

    }
}
